#include "stm32f10x.h"                  // Device header
#include "MySPI.h"
#include "W25Q64_ins.h"

void W25Q64_Init(void)
{
	MySPI_Init();										//先初始化底层的SPI
}

void W25Q64_ReadID(uint8_t* MID,uint16_t* DID)
{
	MySPI_Star();										//先开始
	MySPI_SwapByte(W25Q64_JEDEC_ID);					//输入指令集W25Q64_JEDEC_ID读取ID号，返回值无用，不需要返回值
	*MID = MySPI_SwapByte(W25Q64_DUMMY_BYTE);			//交换接收MID，通过输出参数返回，交换的数据是无用数据，0xff
	*DID = MySPI_SwapByte(W25Q64_DUMMY_BYTE);
	*DID = *DID << 8;									//之前的是高8位，直接需要左移
	*DID |= MySPI_SwapByte(W25Q64_DUMMY_BYTE);			//低八位不能直接给，不然高八位清0了，需要或上第八位才是正确的
	MySPI_Stop();
}

void W25Q64_WriteEnable(void)
{
	MySPI_Star();										//先开始
	MySPI_SwapByte(W25Q64_WRITE_ENABLE);				//交换发送写使能的指令
	MySPI_Stop();
}

void W25Q64_WaitBusy(void)
{
	uint32_t Timeout;
	MySPI_Star();										//先开始
	MySPI_SwapByte(W25Q64_READ_STATUS_REGISTER_1);		//交换发送读状态寄存器1的指令
	Timeout = 100000;									//给定超时计数时间
	while ((MySPI_SwapByte(W25Q64_DUMMY_BYTE) & 0x01) == 0x01)		//就是如果他交换的字节出来的最低一位就是1，就表示忙，
	{	
		Timeout --;								//等待时，计数值自减
		if (Timeout == 0)						//自减到0后，等待超时
		{
			/*超时的错误处理代码，可以添加到此处*/
			break;								//跳出等待，不等了
		}
	}
	MySPI_Stop();
}

/**
  * 函    数：W25Q64页编程
  * 参    数：Address 页编程的起始地址，范围：0x000000~0x7FFFFF
  * 参    数：DataArray	用于写入数据的数组
  * 参    数：Count 要写入数据的数量，范围：0~256
  * 返 回 值：无
  * 注意事项：写入的地址范围不能跨页
  */
void W25Q64_PageProgram(uint32_t Address, uint8_t* DataArray, uint16_t count)
{
	uint16_t i;
	W25Q64_WriteEnable();								//开启写使能
	MySPI_Star();										//开始
	
	MySPI_SwapByte(W25Q64_PAGE_PROGRAM);				//交换发送页编程的指令
	MySPI_SwapByte(Address>>16);						//交换发送地址23~16位
	MySPI_SwapByte(Address>>8);							//交换发送地址15~8位
	MySPI_SwapByte(Address);							//交换发送地址7~0位
	for(i=0; i<count; i++)
	{
		MySPI_SwapByte(DataArray[i]);					//依次在起始地址后写入数据
	}
	MySPI_Stop();
	
	W25Q64_WaitBusy();									//等待忙
}

void W25Q64_SectorErase(uint32_t Address)
{
	W25Q64_WriteEnable();								//开启写使能
	MySPI_Star();										//开始
	
	MySPI_SwapByte(W25Q64_SECTOR_ERASE_4KB);			//交换发送扇区擦除的指令
	MySPI_SwapByte(Address>>16);						//交换发送地址23~16位
	MySPI_SwapByte(Address>>8);							//交换发送地址15~8位
	MySPI_SwapByte(Address);							//交换发送地址7~0位
	
	MySPI_Stop();
	
	W25Q64_WaitBusy();									//等待忙
}

void W25Q64_ReadData(uint32_t Address, uint8_t* DataArray, uint16_t count)
{
	uint32_t i;
	MySPI_Star();										//开始
	MySPI_SwapByte(W25Q64_READ_DATA);					//交换发送读取数据的指令
	MySPI_SwapByte(Address>>16);						//交换发送地址23~16位
	MySPI_SwapByte(Address>>8);							//交换发送地址15~8位
	MySPI_SwapByte(Address);							//交换发送地址7~0位
	for(i=0; i<count; i++)
	{
		DataArray[i] = MySPI_SwapByte(W25Q64_DUMMY_BYTE);
	}
	MySPI_Stop();
}
